/**
 * 
 */
package edu.umd.clip.lm.programs;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

import edu.berkeley.nlp.util.Pair;
import edu.umd.clip.lm.tools.BuildOvertVocabularies;
import edu.umd.clip.lm.tools.EvalTagger;
import edu.umd.clip.lm.tools.FLM2TrainingData;
import edu.umd.clip.lm.tools.HFTTrainerMDI;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class Run {

	private static ArrayList<Pair<String,Class>> programs;
	static {
		programs = new ArrayList<Pair<String,Class>>(20);
		programs.add(new Pair<String,Class>("EvalTagger", EvalTagger.class));
		//programs.add(new Pair<String,Class>("BuildOvertVocabularies", BuildOvertVocabularies.class));
		programs.add(new Pair<String,Class>("FLM2Bin", FLM2TrainingData.class));
		//programs.add(new Pair<String,Class>("HFT", HFTTrainerMDI.class));
		programs.add(new Pair<String,Class>("Decoder", LMDecoder.class));
		programs.add(new Pair<String,Class>("Rescorer", LMRescorer.class));
		programs.add(new Pair<String,Class>("Smoother", LMSmootherEM.class));
		programs.add(new Pair<String,Class>("Trainer", LMNewTrainer.class));
		programs.add(new Pair<String,Class>("Populate", LMClusterPopulator.class));
		programs.add(new Pair<String,Class>("InitModel", InitModel.class));
	}
	
	private static void usage() {
		Iterator<Pair<String,Class>> it = programs.iterator();

		System.out.print("Usage: java -jar lm.jar [");
		System.out.print(it.next().getFirst());
		while(it.hasNext()) {
			System.out.print('|');
			System.out.print(it.next().getFirst());
		}
		System.out.println("] <arguments>");
	}
	/**
	 * @param args
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		if (args.length == 0) {
			usage();
			return;
		}
		
		for(Pair<String,Class> command : programs) {
			if (command.getFirst().equals(args[0])) {
				args = Arrays.copyOfRange(args, 1, args.length);
				Method main = command.getSecond().getMethod("main", String[].class);
				main.invoke(null, (Object)args);
				return;
			}
		}
		usage();
	}

}
